home *** CD-ROM | disk | FTP | other *** search
/ Isometric Game Programming with DirectX 7.0 / Isometric Game Programming.iso / source / chapter7 / isohex7_1 / isohex7_1.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-24  |  11.8 KB  |  473 lines

  1. /*****************************************************************************
  2. IsoHex7_1.cpp
  3. Ernest S. Pazera
  4. 24MAY2000
  5. Start a WIN32 Application Workspace, add in this file
  6. Needs ddraw.lib and dxguid.lib
  7. Needs GDICanvas.h/cpp
  8. Needs DDFuncs.h/cpp
  9. *****************************************************************************/
  10.  
  11. //////////////////////////////////////////////////////////////////////////////
  12. //INCLUDES
  13. //////////////////////////////////////////////////////////////////////////////
  14. #define WIN32_LEAN_AND_MEAN  
  15.  
  16. #include <windows.h>   
  17. #include "GDICanvas.h"
  18. #include "ddraw.h"
  19. #include "DDFuncs.h"
  20.  
  21. //////////////////////////////////////////////////////////////////////////////
  22. //DEFINES
  23. //////////////////////////////////////////////////////////////////////////////
  24. //name for our window class
  25. #define WINDOWCLASS "ISOHEX7"
  26. //title of the application
  27. #define WINDOWTITLE "IsoHex 7-1"
  28.  
  29. //////////////////////////////////////////////////////////////////////////////
  30. //PROTOTYPES
  31. //////////////////////////////////////////////////////////////////////////////
  32. bool Prog_Init();//game data initalizer
  33. void Prog_Loop();//main game loop
  34. void Prog_Done();//game clean up
  35.  
  36. //enumeration functions
  37. HRESULT WINAPI EnumModesCallbackCount(LPDDSURFACEDESC2 lpDDSurfaceDesc, LPVOID lpContext);
  38. HRESULT WINAPI EnumModesCallbackList(LPDDSURFACEDESC2 lpDDSurfaceDesc,LPVOID lpContext);
  39.  
  40. //////////////////////////////////////////////////////////////////////////////
  41. //GLOBALS
  42. //////////////////////////////////////////////////////////////////////////////
  43. HINSTANCE hInstMain=NULL;//main application handle
  44. HWND hWndMain=NULL;//handle to our main window
  45. //IDirectDraw7 Pointer
  46. LPDIRECTDRAW7 lpdd=NULL;
  47. //display mode structure
  48. struct DisplayMode
  49. {
  50.     DWORD dwWidth;
  51.     DWORD dwHeight;
  52.     DWORD dwBPP;
  53. };
  54. //display mode enumeration variables
  55. DWORD dwDisplayModeCount=0;
  56. DisplayMode* DisplayModeList=NULL;
  57.  
  58. //gdicanvas
  59. CGDICanvas gdicBall;
  60.  
  61. //surfaces
  62. LPDIRECTDRAWSURFACE7 lpddsPrime=NULL;
  63. LPDIRECTDRAWSURFACE7 lpddsBack=NULL;
  64. LPDIRECTDRAWSURFACE7 lpddsBall=NULL;
  65.  
  66. //clipper
  67. LPDIRECTDRAWCLIPPER lpddclip=NULL;
  68.  
  69. //size of the display
  70. DWORD dwDisplayWidth=0;
  71. DWORD dwDisplayHeight=0;
  72.  
  73. //position of the ball
  74. POINT ptBallPosition[2];
  75. POINT ptLastPosition[2][2];
  76. //velocity of the ball
  77. POINT ptBallVelocity[2];
  78.  
  79. //paused mode
  80. bool bPaused=false;
  81.  
  82. //////////////////////////////////////////////////////////////////////////////
  83. //WINDOWPROC
  84. //////////////////////////////////////////////////////////////////////////////
  85. LRESULT CALLBACK TheWindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
  86. {
  87.     //which message did we get?
  88.     switch(uMsg)
  89.     {
  90.     case WM_ACTIVATEAPP:
  91.         {
  92.             if(wParam)
  93.             {
  94.                 if(bPaused)
  95.                 {
  96.                     //being activated
  97.                     bPaused=false;
  98.  
  99.                     //restore all surfaces
  100.                     lpdd->RestoreAllSurfaces();
  101.  
  102.                     //clear out back buffer
  103.                     DDBLTFX ddbltfx;
  104.                     DDBLTFX_ColorFill(&ddbltfx,0);
  105.                     lpddsBack->Blt(NULL,NULL,NULL,DDBLT_WAIT | DDBLT_COLORFILL,&ddbltfx);
  106.  
  107.                     //reload ball images
  108.                     LPDDS_ReloadFromFile(lpddsBall,"IsoHex6_4.bmp");
  109.                 }
  110.             }
  111.             else
  112.             {
  113.                 //being deactivated
  114.                 bPaused=true;
  115.             }
  116.         }break;
  117.     case WM_KEYDOWN:
  118.         {
  119.             //check for escape key
  120.             if(wParam==VK_ESCAPE)
  121.             {
  122.                 DestroyWindow(hWndMain);
  123.             }
  124.  
  125.             return(0);//handled message
  126.         }break;
  127.     case WM_DESTROY://the window is being destroyed
  128.         {
  129.  
  130.             //tell the application we are quitting
  131.             PostQuitMessage(0);
  132.  
  133.             //handled message, so return 0
  134.             return(0);
  135.  
  136.         }break;
  137.     case WM_PAINT://the window needs repainting
  138.         {
  139.             //a variable needed for painting information
  140.             PAINTSTRUCT ps;
  141.             
  142.             //start painting
  143.             HDC hdc=BeginPaint(hwnd,&ps);
  144.  
  145.             /////////////////////////////
  146.             //painting code would go here
  147.             /////////////////////////////
  148.  
  149.             //end painting
  150.             EndPaint(hwnd,&ps);
  151.                         
  152.             //handled message, so return 0
  153.             return(0);
  154.         }break;
  155.     }
  156.  
  157.     //pass along any other message to default message handler
  158.     return(DefWindowProc(hwnd,uMsg,wParam,lParam));
  159. }
  160.  
  161.  
  162. //////////////////////////////////////////////////////////////////////////////
  163. //WINMAIN
  164. //////////////////////////////////////////////////////////////////////////////
  165. int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
  166. {
  167.     //assign instance to global variable
  168.     hInstMain=hInstance;
  169.  
  170.     //create window class
  171.     WNDCLASSEX wcx;
  172.  
  173.     //set the size of the structure
  174.     wcx.cbSize=sizeof(WNDCLASSEX);
  175.  
  176.     //class style
  177.     wcx.style=CS_OWNDC | CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
  178.  
  179.     //window procedure
  180.     wcx.lpfnWndProc=TheWindowProc;
  181.  
  182.     //class extra
  183.     wcx.cbClsExtra=0;
  184.  
  185.     //window extra
  186.     wcx.cbWndExtra=0;
  187.  
  188.     //application handle
  189.     wcx.hInstance=hInstMain;
  190.  
  191.     //icon
  192.     wcx.hIcon=LoadIcon(NULL,IDI_APPLICATION);
  193.  
  194.     //cursor
  195.     wcx.hCursor=LoadCursor(NULL,IDC_ARROW);
  196.  
  197.     //background color
  198.     wcx.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
  199.  
  200.     //menu
  201.     wcx.lpszMenuName=NULL;
  202.  
  203.     //class name
  204.     wcx.lpszClassName=WINDOWCLASS;
  205.  
  206.     //small icon
  207.     wcx.hIconSm=NULL;
  208.  
  209.     //register the window class, return 0 if not successful
  210.     if(!RegisterClassEx(&wcx)) return(0);
  211.  
  212.     //create main window
  213.     hWndMain=CreateWindowEx(0,WINDOWCLASS,WINDOWTITLE, WS_POPUP | WS_VISIBLE,0,0,320,240,NULL,NULL,hInstMain,NULL);
  214.  
  215.     //error check
  216.     if(!hWndMain) return(0);
  217.  
  218.     //if program initialization failed, then return with 0
  219.     if(!Prog_Init()) return(0);
  220.  
  221.     //message structure
  222.     MSG msg;
  223.  
  224.     //message pump
  225.     for(;;)    
  226.     {
  227.         //look for a message
  228.         if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
  229.         {
  230.             //there is a message
  231.  
  232.             //check that we arent quitting
  233.             if(msg.message==WM_QUIT) break;
  234.             
  235.             //translate message
  236.             TranslateMessage(&msg);
  237.  
  238.             //dispatch message
  239.             DispatchMessage(&msg);
  240.         }
  241.  
  242.         //run main game loop
  243.         Prog_Loop();
  244.     }
  245.     
  246.     //clean up program data
  247.     Prog_Done();
  248.  
  249.     //return the wparam from the WM_QUIT message
  250.     return(msg.wParam);
  251. }
  252.  
  253. //////////////////////////////////////////////////////////////////////////////
  254. //INITIALIZATION
  255. //////////////////////////////////////////////////////////////////////////////
  256. bool Prog_Init()
  257. {
  258.     lpdd=LPDD_Create(hWndMain,DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT);
  259.  
  260.     //enumerate the displaymodes
  261.     dwDisplayModeCount=0;
  262.  
  263.     lpdd->EnumDisplayModes(0,NULL,NULL,EnumModesCallbackCount);
  264.  
  265.     DisplayModeList=new DisplayMode[dwDisplayModeCount];
  266.     dwDisplayModeCount=0;
  267.  
  268.     lpdd->EnumDisplayModes(0,NULL,NULL,EnumModesCallbackList);
  269.  
  270.     //pick a display mode
  271.     DisplayMode TestMode;
  272.     TestMode.dwWidth=0;
  273.     TestMode.dwHeight=0;
  274.     TestMode.dwBPP=0;
  275.     DWORD index;
  276.     bool found=false;
  277.  
  278.     for(index=0;(index<dwDisplayModeCount);index++)
  279.     {
  280.         if(DisplayModeList[index].dwBPP==16)
  281.         {
  282.             if(DisplayModeList[index].dwWidth>TestMode.dwWidth)
  283.             {
  284.                 TestMode.dwWidth=DisplayModeList[index].dwWidth;
  285.                 TestMode.dwHeight=DisplayModeList[index].dwHeight;
  286.                 TestMode.dwBPP=DisplayModeList[index].dwBPP;
  287.                 found=true;
  288.             }
  289.         }
  290.     }
  291.  
  292.     if(!found)
  293.     {
  294.         return(false);
  295.     }
  296.  
  297.     //set the display mode
  298.     lpdd->SetDisplayMode(TestMode.dwWidth,TestMode.dwHeight,TestMode.dwBPP,0,0);
  299.     //keep display width and height in global variables
  300.     dwDisplayWidth=TestMode.dwWidth;
  301.     dwDisplayHeight=TestMode.dwHeight;
  302.  
  303.     //create the primary surface with a single back buffer
  304.     lpddsPrime=LPDDS_CreatePrimary(lpdd,1);
  305.  
  306.     //retrieve back buffer
  307.     lpddsBack=LPDDS_GetSecondary(lpddsPrime);
  308.  
  309.     //do an initial clearing out of the back buffer
  310.     DDBLTFX ddbltfx;
  311.     DDBLTFX_ColorFill(&ddbltfx,0);
  312.  
  313.     //do a color fill
  314.     lpddsBack->Blt(NULL,NULL,NULL,DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx);
  315.  
  316.     //create the region
  317.     HRGN hrgn=CreateRectRgn(0+32,0+32,dwDisplayWidth-32,dwDisplayHeight-32);
  318.  
  319.     //set up clipper
  320.     lpddclip=LPDDCLIP_Create(lpdd,hrgn);
  321.  
  322.     //delete region
  323.     DeleteObject(hrgn);
  324.  
  325.     //attach clipper
  326.     lpddsBack->SetClipper(lpddclip);
  327.  
  328.     //load in the ball image
  329.     gdicBall.Load(NULL,"IsoHex7_1.bmp");
  330.  
  331.     //create an offscreen surface to contain the ball
  332.     lpddsBall=LPDDS_LoadFromFile(lpdd,"IsoHex7_1.bmp");
  333.  
  334.     //create a black color key
  335.     LPDDS_SetSrcColorKey(lpddsBall,0);
  336.  
  337.     //initialize ball position and velocity
  338.     ptBallPosition[0].x=0;
  339.     ptBallPosition[0].y=0;
  340.     ptLastPosition[0][0].x=0;
  341.     ptLastPosition[0][0].y=0;
  342.     ptLastPosition[0][1].x=0;
  343.     ptLastPosition[0][1].y=0;
  344.     ptBallPosition[1].x=0;
  345.     ptBallPosition[1].y=0;
  346.     ptLastPosition[1][0].x=0;
  347.     ptLastPosition[1][0].y=0;
  348.     ptLastPosition[1][1].x=0;
  349.     ptLastPosition[1][1].y=0;
  350.  
  351.     ptBallVelocity[0].x=4;
  352.     ptBallVelocity[0].y=2;
  353.     ptBallVelocity[1].x=2;
  354.     ptBallVelocity[1].y=4;
  355.  
  356.     return(true);//return success
  357. }
  358.  
  359. //////////////////////////////////////////////////////////////////////////////
  360. //CLEANUP
  361. //////////////////////////////////////////////////////////////////////////////
  362. void Prog_Done()
  363. {    
  364.     //clean up clipper
  365.     LPDDCLIP_Release(&lpddclip);
  366.  
  367.     //clean up ball surface
  368.     LPDDS_Release(&lpddsBall);
  369.         
  370.     //clean up primary surface(this will clean up the back buffer, also)
  371.     LPDDS_Release(&lpddsPrime);
  372.  
  373.     //clean up the dd pointer
  374.     LPDD_Release(&lpdd);
  375.  
  376.     //clean up gdicanvas
  377.     gdicBall.Destroy();
  378.  
  379.     //get rid of enumeration stuff
  380.     delete [] DisplayModeList;
  381. }
  382.  
  383. //////////////////////////////////////////////////////////////////////////////
  384. //MAIN GAME LOOP
  385. //////////////////////////////////////////////////////////////////////////////
  386. void Prog_Loop()
  387. {
  388.     //if paused, return without doing anything
  389.     if(bPaused) return;
  390.  
  391.     int index;
  392.  
  393.     for(index=0;index<2;index++)
  394.     {
  395.  
  396.     //set up rectangle for filling
  397.     RECT rcFill;
  398.     SetRect(&rcFill,ptLastPosition[index][0].x,ptLastPosition[index][0].y,ptLastPosition[index][0].x+gdicBall.GetWidth(),ptLastPosition[index][0].y+gdicBall.GetHeight());
  399.  
  400.     //set up a ddbltfx
  401.     DDBLTFX ddbltfx;
  402.     DDBLTFX_ColorFill(&ddbltfx,0);
  403.  
  404.     //blt the color fill to the back buffer
  405.     lpddsBack->Blt(&rcFill,NULL,NULL,DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx);
  406.     }
  407.  
  408.     for(index=0;index<2;index++)
  409.     {
  410.     //set up source and destination rects for blitting the ball
  411.     RECT rcSrc;
  412.     RECT rcDst;
  413.  
  414.     SetRect(&rcSrc,0,0,gdicBall.GetWidth(),gdicBall.GetHeight());
  415.     CopyRect(&rcDst,&rcSrc);
  416.     OffsetRect(&rcDst,ptBallPosition[index].x,ptBallPosition[index].y);
  417.  
  418.     //blit the ball
  419.     lpddsBack->Blt(&rcDst,lpddsBall,&rcSrc,DDBLT_WAIT | DDBLT_KEYSRC, NULL);
  420.  
  421.     //copy current position of ball to old position
  422.     ptLastPosition[index][0]=ptLastPosition[index][1];
  423.     ptLastPosition[index][1]=ptBallPosition[index];
  424.  
  425.     //move the ball
  426.     ptBallPosition[index].x+=ptBallVelocity[index].x;
  427.     ptBallPosition[index].y+=ptBallVelocity[index].y;
  428.  
  429.     //bounds checking
  430.     //left side
  431.     if(ptBallPosition[index].x<=0) ptBallVelocity[index].x=abs(ptBallVelocity[index].x);
  432.     //top side
  433.     if(ptBallPosition[index].y<=0) ptBallVelocity[index].y=abs(ptBallVelocity[index].y);
  434.     //right side
  435.     if(ptBallPosition[index].x>=(int)dwDisplayWidth-gdicBall.GetWidth()) ptBallVelocity[index].x=-abs(ptBallVelocity[index].x);
  436.     //bottom side
  437.     if(ptBallPosition[index].y>=(int)dwDisplayHeight-gdicBall.GetHeight()) ptBallVelocity[index].y=-abs(ptBallVelocity[index].y);
  438.     }
  439.     //flip surfaces
  440.     lpddsPrime->Flip(NULL,DDFLIP_WAIT);
  441. }
  442.  
  443. //enumeration-count
  444. HRESULT WINAPI EnumModesCallbackCount(
  445.   LPDDSURFACEDESC2 lpDDSurfaceDesc,  
  446.   LPVOID lpContext                   
  447. )
  448. {
  449.     //increment the count variable
  450.     dwDisplayModeCount++;
  451.  
  452.     //continue the enumeration
  453.     return(DDENUMRET_OK);
  454. }
  455.  
  456. //enumeration-list
  457. HRESULT WINAPI EnumModesCallbackList(
  458.   LPDDSURFACEDESC2 lpDDSurfaceDesc,  
  459.   LPVOID lpContext                   
  460. )
  461. {
  462.     //copy applicable information to the list
  463.     DisplayModeList[dwDisplayModeCount].dwWidth=lpDDSurfaceDesc->dwWidth;
  464.     DisplayModeList[dwDisplayModeCount].dwHeight=lpDDSurfaceDesc->dwHeight;
  465.     DisplayModeList[dwDisplayModeCount].dwBPP=lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount;
  466.  
  467.     //increment the count variable
  468.     dwDisplayModeCount++;
  469.  
  470.     //continue the enumeration
  471.     return(DDENUMRET_OK);
  472. }
  473.